﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using GestureEventArgs = System.Windows.Input.GestureEventArgs;

namespace GBAExtentionLib
{
    [TemplatePart(Name = FileList, Type = typeof (ListBox))]
    [TemplatePart(Name = CurrentFolderText, Type = typeof(TextBlock))]
    [TemplatePart(Name = RefreshButton, Type = typeof(Button))]
    public class DirectoryWatcher : Control
    {
        private readonly int _fontSize = 24;
        private readonly Brush _foregroundBrush = new SolidColorBrush(Colors.White);
        private readonly Thickness _margin=new Thickness(12);

        #region TemplatePart Name

        private const string FileList = "FileList";
        private const string CurrentFolderText = "CurrentFolderText";
        private const string RefreshButton = "RefreshButton";

        #endregion

        #region TemplatePart

        private ListBox _fileList;
        private TextBlock _currentFolderText;
        private Button _refreshButton;

        #endregion

        #region Constructor

        public DirectoryWatcher()
        {
            DefaultStyleKey = typeof (DirectoryWatcher);
            
        }

        #endregion

        #region Override

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _fileList = GetTemplateChild(FileList) as ListBox;
            _currentFolderText = GetTemplateChild(CurrentFolderText) as TextBlock;
            _refreshButton = GetTemplateChild(RefreshButton) as Button;
            if (_refreshButton != null)
                _refreshButton.Click += (sender, e) =>
                    {
                        var dir = CurrentDirectory == null || CurrentDirectory.NodeElement == null ||
                                  string.IsNullOrEmpty(CurrentDirectory.NodeElement.FullName)
                                      ? ""
                                      : CurrentDirectory.NodeElement.FullName;
                    CurrentDirectory = IsolatedStorageExtentions.GetFileTree(dir, FileExtention);
                    };
            CurrentDirectory = IsolatedStorageExtentions.GetFileTree("", FileExtention);
        }

        #endregion

        #region 依赖属性

        private static readonly DependencyProperty CurrentDirectoryProperty =
            DependencyProperty.Register("CurrentDirectory", typeof (IsolatedStorageFileTree), typeof (DirectoryWatcher),
                                        new PropertyMetadata(CurrentFileTreeChanged));

        private IsolatedStorageFileTree CurrentDirectory
        {
            get { return (IsolatedStorageFileTree) GetValue(CurrentDirectoryProperty); }
            set { SetValue(CurrentDirectoryProperty, value); }
        }

        public static readonly DependencyProperty GestureTypeProperty =
            DependencyProperty.Register("GestureType", typeof (GestureMode), typeof (DirectoryWatcher),
                                        new PropertyMetadata(GestureMode.Tap, CurrentFileTreeChanged));

        public GestureMode GestureType
        {
            get { return (GestureMode) GetValue(GestureTypeProperty); }
            set { SetValue(GestureTypeProperty, value); }
        }

        public static readonly DependencyProperty FileExtentionProperty =
            DependencyProperty.Register("FileExtention", typeof(string), typeof(DirectoryWatcher), new PropertyMetadata("",FileExtentionChanged));

        public string FileExtention
        {
            get { return (string) GetValue(FileExtentionProperty); }
            set { SetValue(FileExtentionProperty, value); }
        }

        private static void CurrentFileTreeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            ((DirectoryWatcher) obj).UpdateFileTree();
        }

        static void FileExtentionChanged(DependencyObject obj,DependencyPropertyChangedEventArgs e)
        {
            ((DirectoryWatcher)obj).CurrentDirectory = IsolatedStorageExtentions.GetFileTree("", ((DirectoryWatcher)obj).FileExtention);
        }

        #endregion

        #region 私有方法

        private void UpdateFileTree()
        {
            if (_fileList == null) return;
            _fileList.Items.Clear();
            _fileList.Items.Add(GenerateItem(null));
            if (CurrentDirectory != null)
            {
                if (_currentFolderText != null)
                    _currentFolderText.Text = CurrentDirectory.NodeElement==null?"根目录":CurrentDirectory.NodeElement.FullName;
                foreach (var isolatedStorageFileTree in CurrentDirectory.Children)
                {
                    _fileList.Items.Add(GenerateItem(isolatedStorageFileTree));
                }
            }
        }

        private FrameworkElement GenerateItem(IsolatedStorageFileTree node)
        {
            var grid = new Grid{Background = new SolidColorBrush(Colors.Black){Opacity = 0},MinWidth = 696};
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1,GridUnitType.Star) });
            var image = new Image {Width = _fontSize, Height = _fontSize};
            grid.Children.Add(image);
            Grid.SetColumn(image,0);
            var textblock = new TextBlock
                {
                    FontSize = _fontSize,
                    Foreground = _foregroundBrush,
                    Margin = _margin,
                    TextTrimming = TextTrimming.WordEllipsis
                };
            grid.Children.Add(textblock);
            Grid.SetColumn(textblock,1);
            if (node == null || node.IsRootNode)
            {
                textblock.Text = "...上一层";
                image.Source = new BitmapImage(new Uri("/GBAExtentionLib;component/Images/FolderUp.png", UriKind.Relative));
                switch (GestureType)
                {
                    case GestureMode.Tap:
                        grid.Tap += GoUpLevelTap;
                        break;
                    case GestureMode.DoubleTap:
                        grid.DoubleTap += GoUpLevelTap;
                        break;
                }
            }
            else
            {
                textblock.Text = string.Format("{0}", node.NodeElement.Name);
                grid.DataContext = node;
                switch (GestureType)
                {
                    case GestureMode.Tap:
                        if (node.NodeType == IsolatedStorageFileNodeType.Directory)
                            grid.Tap += GoDownLevelTap;
                        else
                            grid.Tap += FileTap;
                        break;
                    case GestureMode.DoubleTap:
                        if (node.NodeType == IsolatedStorageFileNodeType.Directory)
                            grid.DoubleTap += GoDownLevelTap;
                        else
                            grid.DoubleTap += FileTap;
                        break;
                }

                image.Source = new BitmapImage(new Uri(string.Format("/GBAExtentionLib;component/Images/{0}.png", node.NodeType == IsolatedStorageFileNodeType.Directory ? "Folder" : "GameFile"), UriKind.Relative));
            }
            return grid;
        }

        #endregion

        #region 事件处理

        private void FileTap(object sender, GestureEventArgs e)
        {
            if(FileSelected!=null)
                FileSelected.Invoke(this, new FileSelectorEvent { SelectedFile = ((IsolatedStorageFileTree)((FrameworkElement)sender).DataContext).NodeElement });
        }

        private void GoDownLevelTap(object sender, GestureEventArgs e)
        {
            CurrentDirectory = ((IsolatedStorageFileTree)((FrameworkElement)sender).DataContext);
        }

        private void GoUpLevelTap(object sender, GestureEventArgs e)
        {
            if (CurrentDirectory.Parent != null)
            {
                CurrentDirectory = CurrentDirectory.Parent;
            }
            else
            {
#if DEBUG
                MessageBox.Show("It's TopMost Folder");
#endif
            }
        }

        #endregion

        #region 自定义事件

        public delegate void FileSelectedHandler(object sender, FileSelectorEvent e);

        /// <summary>
        /// 文件选择变化的事件
        /// </summary>
        public event FileSelectedHandler FileSelected;

        #endregion

    }

    public class FileSelectorEvent:EventArgs
    {
        public IIsolatedStorageFile SelectedFile { get; set; }
    }

    public enum GestureMode
    {
        Tap,
        DoubleTap
    }

}